import Controller from './Controller';
import GUI from './GUI.js';

export default class OptionEditController extends Controller {

	constructor( parent, object, property, options, config) {
		if(config == null) config = {} ;

		super( parent, object, property, 'inputOption', 'div', config );
		const that = this ;
		let type = config.type ;
		if(type == null || type == "") type = "text" ;
		this.$input = document.createElement( 'input' );
		this.$input.setAttribute( 'type', type );
		this.$input.setAttribute( 'spellcheck', 'false' );
		this.$input.setAttribute( 'aria-labelledby', this.$name.id );

		this.$display = document.createElement( 'div' );
		this.$display.classList.add( 'display' );


		this.$panel = document.createElement( 'div' );
		this.$panel.classList.add( 'panel' );

		this.dataObj = options ;

		//选项是否为颜色
		this.optionCallback = config.optionCallback ;
		for(let name in options) {
			const $option = document.createElement( 'div' );
			$option.classList.add( 'inputOptionDiv' );
			$option.innerHTML = name;
			$option.setAttribute("data-id",options[name]) ;
			if(this.optionCallback != null)
				this.optionCallback(this.$panel,$option,name) ;
			this.$panel.appendChild( $option );
		}

		//按钮
		if(config != null && config.btnEnable === true){
			let btnTxt = config.btnTxt ;
			if(btnTxt != null && btnTxt != "" && config.btnClick != null){
				this.$button1 = document.createElement( 'button' );
				this.$button1.innerHTML = btnTxt;
				this.$button1.classList.add("optionBtn") ;

				this.$button1.addEventListener( 'click', e => {
					e.preventDefault();
					config.btnClick.call(null, this.getValue(),this,object);
				} );
			}
		}

		this.isEnter = false ;
		this.enterTrigger = false ;
		let keydownEvent = config.onKeydown ;
		let keyupEvent = config.onKeyup ;

		this.$input.addEventListener( 'input', () => {
			this.setValue( this.$input.value );
		} );

		this.$input.addEventListener( 'keydown', e => {
			if ( e.code === 'Enter' ) {
				this.hidePanel() ;
				this.isEnter = true ;
				if(this.enterTrigger == true) {
					this._changed = true;
					this._callOnFinishChange();
				}else
					this.$input.blur();
			}else {
				this.isEnter = false ;
			}
			if(GUI.onKeydown != null) GUI.onKeydown(e,this.$input,this) ;
			if(keydownEvent != null)
				keydownEvent(e,this.$input,this) ;
		} );

		this.$input.addEventListener( 'keyup', e => {
			if(GUI.onKeyup != null) GUI.onKeyup(e,this.$input,this) ;
			if(keyupEvent != null)
				keyupEvent(e,this.$input,this) ;
		} );

		this.$input.addEventListener( 'blur', () => {
			this.timerId = window.setTimeout( () => that.hidePanel(),200) ;
			this._callOnFinishChange();
		} );

		this.loadOptionFunc = null ;
		this.$widget.addEventListener( 'click', e => {
			if(e.target != null && e.target.classList.contains('inputOptionDiv') == false) {
				if(this.loadOptionFunc != null && !this.isPanelShow()) {
					//只加载一次
					if(this.hadLoadOptions !== true) {
						this.hadLoadOptions = this.loadOptionFunc( this );
					}
				}
				// this.showPanel() ;
				if(this.timerId != null)
					window.clearTimeout(this.timerId) ;
				this.toggerPanel() ;
			}

		} );

		this.$panel.addEventListener("click",e => {
			that.hidePanel() ;
			if(e.target != null && e.target.classList.contains('inputOptionDiv') == true) {
				let value = e.target.getAttribute("data-id");
				let text = e.target.innerHTML ;
				this.setValue( value );
				if(this.selectCallback != null)
					this.selectCallback(value,text,this) ;
			}
		}) ;

		this.$widget.appendChild( this.$input );
		this.$widget.appendChild( this.$display );
		this.$widget.appendChild( this.$panel );

		this._appendEndDomHtml(config.endHtml) ;
		// this.bindPanelEvent() ;
		this.$disable = this.$input;

		this.updateDisplay();
	}

	/**
	 * 加载数据触发
	 * @param callback 返回true后不再触发
	 */
	onLoadOptions(callback){
		this.loadOptionFunc = callback ;
		return this ;
	}

	onSelect(callback) {
		this.selectCallback = callback ;
		return this ;
	}

	setPanelWidth(width){
		if(width == null || width === "") return this ;
		this.$panel.style.width = width + 'px' ;
		return this ;
	}

	/**
	 * 结束点击时通知的数据更新事件
	 * @returns {OptionEditController}
	 */
	finishTriggerLoadOptions(){
		this.hadLoadOptions = true ;
		return this ;
	}

	/**
	 * 回车时，触发finish事件，并且不触发失去焦点行为，主要用于查询条件
	 * @returns {StringController}
	 */
	enterTriggerFinish(){
		this.enterTrigger = true ;
		return this ;
	}

	updateDisplay() {
		let value = this.getValue() ;
		if(value == null) value = '' ;
		this.$input.value = value ;
		return this;
	}

	updateOptions( options){
		this.$panel.innerHTML = '' ;
		for(let name in options) {
			const $option = document.createElement( 'div' );
			$option.classList.add( 'inputOptionDiv' );
			$option.innerHTML = name;
			$option.setAttribute("data-id",options[name]) ;
			if(this.optionCallback != null)
				this.optionCallback(this.$panel,$option,name) ;
			this.$panel.appendChild( $option );
		} ;
		this.dataObj = options ;
		this.updateDisplay() ;
	}

	isPanelShow(){
		return this.$panel.style.display === 'flex' ;
	}

	toggerPanel(){
		if(this.$panel.style.display == 'flex')
			this.hidePanel() ;
		else
			this.showPanel() ;
	}

	/**
	 * 显示下拉选项
	 */
	showPanel(){
		//判断当前值是否存在
		let value = this.getValue() ;
		if(this.dataObj != null && value != null && value != "") {
			let needAppend = true ;
			for(let name in this.dataObj) {
				if(this.dataObj[name] == value) {
					needAppend = false ;
					break
				}
			}
			if(needAppend === true) {
				const $option = document.createElement( 'div' );
				$option.classList.add( 'inputOptionDiv' );
				$option.innerHTML = value;
				$option.setAttribute("data-id",value) ;
				if(this.$panel.firstChild == null)
					this.$panel.appendChild($option);
				else
					this.$panel.insertBefore($option, this.$panel.firstChild);
				this.dataObj[value] = value ;
			}
		}
		//计算文本框的高度
		this.$panel.style.top = (this.$input.getBoundingClientRect().height - 5) + 'px' ;
		this.$panel.style.display = 'flex' ;
		this.$input.focus() ;
	}

	hidePanel(){
		this.$panel.style.display = 'none' ;
	}

	setStyle(style){
		if(style == null) return this ;
		if(this.$input == null) return this;
		this.$input.setAttribute("style",style) ;
		this.$display.setAttribute("style",style) ;
		return this ;
	}

	addClass(clazz){
		if(clazz == null || clazz == "") return this ;
		if(this.$input == null) return this;
		this.$input.classList.add(clazz) ;
		this.$display.classList.add(clazz) ;
		return this ;
	}

	removeClass(clazz){
		if(clazz == null || clazz == "") return this;
		if(this.$input == null) return this;
		this.$input.classList.remove(clazz) ;
		this.$display.classList.remove(clazz) ;
		return this ;
	}

	addDisplayClass(clazz){
		if(clazz == null || clazz == "") return this ;
		if(this.$display == null) return this;
		this.$display.classList.add(clazz) ;
		return this ;
	}

	removeDisplayClass(clazz){
		if(clazz == null || clazz == "") return this;
		if(this.$display == null) return this;
		this.$display.classList.remove(clazz) ;
		return this ;
	}
}
